/**
 * 统一事件总线系统
 * 通过 module 字段实现模块化事件路由，支持完全动态的模块名称
 *
 * 特性：
 * - 统一的事件数据结构
 * - 动态模块名称，无需维护常量
 * - 类型安全的泛型支持
 * - 灵活的事件过滤
 * - 向后兼容旧的专用事件方法
 */

// ===== 类型定义 =====

/**
 * 统一事件数据结构
 */
export interface IUnifiedEventData<T = any> {
  /** 模块名称，用于事件路由和过滤 */
  module: string;
  /** 操作类型 */
  action: 'add' | 'edit' | 'delete' | 'refresh' | 'custom';
  /** 数据ID */
  id?: string | number;
  /** 事件携带的数据 */
  data?: T;
  /** 自定义操作类型（当action为custom时使用） */
  customAction?: string;
  /** 事件时间戳 */
  timestamp?: number;
  /** 额外的元数据 */
  metadata?: Record<string, any>;
}

/**
 * 事件监听器回调函数类型
 */
export type IEventCallback<T = any> = (eventData: IUnifiedEventData<T>) => void;

/**
 * 事件过滤器配置
 */
export interface IEventFilter {
  /** 模块名称过滤 */
  modules?: string[];
  /** 操作类型过滤 */
  actions?: string[];
  /** 自定义过滤函数 */
  customFilter?: (eventData: IUnifiedEventData) => boolean;
}

/**
 * 模块名称类型
 * 支持任意字符串作为模块名称，完全动态化
 */
export type ModuleName = string;

/**
 * 常用模块名称示例（仅供参考，可以使用任意字符串）
 */
export const COMMON_MODULE_NAMES = {
  VISITOR_INFO: 'visitor-info',
  ACTIVITY: 'activity',
  USER_INFO: 'user-info',
  HR: 'hr',
  NOTIFICATION: 'notification',
  WORKFLOW: 'workflow',
  DOCUMENT: 'document',
  COMMON_DATA: 'common-data',
} as const;

// ===== 事件名称常量 =====

/**
 * 统一事件名称
 */
export const UNIFIED_EVENT_NAME = 'unified-module-event';

// ===== 核心事件系统 =====

/**
 * 统一事件发送方法
 * @param module 模块名称
 * @param action 操作类型
 * @param options 事件选项
 */
export function emitUnifiedEvent<T = any>(
  module: ModuleName,
  action: IUnifiedEventData['action'],
  options: {
    id?: string | number;
    data?: T;
    customAction?: string;
    metadata?: Record<string, any>;
  } = {}
): void {
  const eventData: IUnifiedEventData<T> = {
    module,
    action,
    id: options.id,
    data: options.data,
    customAction: options.customAction,
    timestamp: Date.now(),
    metadata: options.metadata,
  };

  console.log(`[统一事件系统] 发送事件:`, eventData);
  uni.$emit(UNIFIED_EVENT_NAME, eventData);
}

/**
 * 统一事件监听方法
 * @param callback 回调函数
 * @param filter 事件过滤器（可选）
 * @returns 取消监听的函数
 */
export function onUnifiedEvent<T = any>(
  callback: IEventCallback<T>,
  filter?: IEventFilter
): () => void {
  const wrappedCallback = (eventData: IUnifiedEventData<T>) => {
    // 应用过滤器
    if (filter && !shouldProcessEvent(eventData, filter)) {
      return;
    }

    console.log(`[统一事件系统] 处理事件:`, eventData);
    callback(eventData);
  };

  uni.$on(UNIFIED_EVENT_NAME, wrappedCallback);

  // 返回取消监听的函数
  return () => {
    uni.$off(UNIFIED_EVENT_NAME, wrappedCallback);
  };
}

/**
 * 移除统一事件监听
 * @param callback 要移除的回调函数（可选，不传则移除所有监听）
 */
export function offUnifiedEvent(callback?: IEventCallback): void {
  if (callback) {
    uni.$off(UNIFIED_EVENT_NAME, callback);
  } else {
    uni.$off(UNIFIED_EVENT_NAME);
  }
}

/**
 * 按模块监听事件的便捷方法
 * @param module 模块名称
 * @param callback 回调函数
 * @param actions 可选的操作类型过滤
 * @returns 取消监听的函数
 */
export function onModuleEvent<T = any>(
  module: ModuleName,
  callback: IEventCallback<T>,
  actions?: string[]
): () => void {
  return onUnifiedEvent(callback, {
    modules: [module],
    actions,
  });
}

/**
 * 按模块和操作类型监听事件的便捷方法
 * @param module 模块名称
 * @param action 操作类型
 * @param callback 回调函数
 * @returns 取消监听的函数
 */
export function onModuleAction<T = any>(
  module: ModuleName,
  action: string,
  callback: IEventCallback<T>
): () => void {
  return onUnifiedEvent(callback, {
    modules: [module],
    actions: [action],
  });
}

/**
 * 判断事件是否应该被处理（基于过滤器）
 * @param eventData 事件数据
 * @param filter 过滤器配置
 * @returns 是否应该处理该事件
 */
function shouldProcessEvent(
  eventData: IUnifiedEventData,
  filter: IEventFilter
): boolean {
  // 模块名称过滤
  if (filter.modules && filter.modules.length > 0) {
    if (!filter.modules.includes(eventData.module)) {
      return false;
    }
  }

  // 操作类型过滤
  if (filter.actions && filter.actions.length > 0) {
    const actionToCheck = eventData.action === 'custom'
      ? eventData.customAction
      : eventData.action;

    if (!actionToCheck || !filter.actions.includes(actionToCheck)) {
      return false;
    }
  }

  // 自定义过滤函数
  if (filter.customFilter && !filter.customFilter(eventData)) {
    return false;
  }

  return true;
}

/**
 * 清除所有统一事件监听
 */
export function clearAllUnifiedEventListeners(): void {
  uni.$off(UNIFIED_EVENT_NAME);
}

/**
 * 创建模块专用事件对象的工厂函数
 * 使用此函数可以为任何模块创建专用的事件对象，无需修改任何配置文件
 *
 * @param moduleName 模块名称
 * @returns 模块专用的事件对象
 *
 * @example
 * // 为新模块创建事件对象
 * const NotificationEvents = createModuleEvents('notification');
 * NotificationEvents.emit('add', { id: '123', data: notificationData });
 * const unsubscribe = NotificationEvents.on((eventData) => { ... });
 */
export function createModuleEvents(moduleName: string) {
  return {
    emit: (action: IUnifiedEventData['action'], options: Parameters<typeof emitUnifiedEvent>[2] = {}) =>
      emitUnifiedEvent(moduleName, action, options),

    on: <T = any>(callback: IEventCallback<T>, actions?: string[]) =>
      onModuleEvent(moduleName, callback, actions),

    onAdd: <T = any>(callback: IEventCallback<T>) =>
      onModuleAction(moduleName, 'add', callback),

    onEdit: <T = any>(callback: IEventCallback<T>) =>
      onModuleAction(moduleName, 'edit', callback),

    onDelete: <T = any>(callback: IEventCallback<T>) =>
      onModuleAction(moduleName, 'delete', callback),

    onRefresh: <T = any>(callback: IEventCallback<T>) =>
      onModuleAction(moduleName, 'refresh', callback),

    onCustom: <T = any>(callback: IEventCallback<T>) =>
      onModuleAction(moduleName, 'custom', callback),
  };
}

// ===== 便捷的模块专用方法 =====

/**
 * 访客信息模块事件方法
 * 使用动态模块名称 'visitor-info'
 */
export const VisitorInfoEvents = createModuleEvents('visitor-info');

/**
 * 活动模块事件方法
 * 使用动态模块名称 'activity'
 */
export const ActivityEvents = {
  ...createModuleEvents('activity'),
  // 活动模块特有的便捷方法
  onJoin: <T = any>(callback: IEventCallback<T>) =>
    onModuleAction('activity', 'join', callback),
};

/**
 * 用户信息模块事件方法
 * 使用动态模块名称 'user-info'
 */
export const UserInfoEvents = {
  ...createModuleEvents('user-info'),
  // 用户模块特有的便捷方法
  onUpdate: <T = any>(callback: IEventCallback<T>) =>
    onModuleAction('user-info', 'edit', callback),

  onAvatarUpdate: <T = any>(callback: IEventCallback<T>) =>
    onModuleAction('user-info', 'avatar-update', callback),
};

/**
 * HR退休申请单模块事件方法
 * 使用动态模块名称 'hr-retire-request'
 */
export const RetireInfoEvents = createModuleEvents('hr-retire-request');

/**
 * HR离职办理单模块事件方法
 * 使用动态模块名称 'hr-resign-request'
 */
export const ResignInfoEvents = createModuleEvents('hr-resign-request');

/**
 * HR合同续签单模块事件方法
 * 使用动态模块名称 'hr-renew-request'
 */
export const RenewInfoEvents = createModuleEvents('hr-renew-request');

/**
 * HR转正申请单模块事件方法
 * 使用动态模块名称 'hr-probation-request'
 */
export const ProbationInfoEvents = createModuleEvents('hr-probation-request');

/**
 * HR入职申请单模块事件方法
 * 使用动态模块名称 'hr-onboarding-request'
 */
export const OnboardingInfoEvents = createModuleEvents('hr-onboarding-request');

/**
 * HR面试申请单模块事件方法
 * 使用动态模块名称 'hr-interview-request'
 */
export const InterviewInfoEvents = createModuleEvents('hr-interview-request');

// ===== 旧版事件名称常量（向后兼容） =====

// 定义事件名称常量，便于维护和使用
export const EVENT_NAMES = {
  // 数据更新事件
  DATA_UPDATED: 'data-updated',
  // 活动相关事件
  ACTIVITY_UPDATED: 'activity-updated',
  ACTIVITY_CREATED: 'activity-created',
  ACTIVITY_DELETED: 'activity-deleted',
  ACTIVITY_JOINED: 'activity-joined',
  // 访客信息相关事件
  VISITOR_INFO_UPDATED: 'visitor-info-updated',
  VISITOR_INFO_CREATED: 'visitor-info-created',
  VISITOR_INFO_DELETED: 'visitor-info-deleted',
  // 用户相关事件
  USER_INFO_UPDATED: 'user-info-updated',
  USER_AVATAR_UPDATED: 'user-avatar-updated',
  USER_PROFILE_UPDATED: 'user-profile-updated',
  // 通用刷新事件
  REFRESH_PAGE: 'refresh-page',
};

/**
 * 发布数据更新事件
 * @param type 更新的数据类型
 * @param id 更新的数据ID
 * @param action 执行的操作类型：add/edit/delete
 */
export function emitDataUpdate(type: string, id: string | number, action: 'add' | 'edit' | 'delete') {
  uni.$emit(EVENT_NAMES.DATA_UPDATED, { type, id, action });
}

/**
 * 监听数据更新事件
 * @param callback 回调函数
 */
export function onDataUpdate(callback: (data: { type: string; id: string | number; action: string }) => void) {
  uni.$on(EVENT_NAMES.DATA_UPDATED, callback);
}

/**
 * 移除数据更新监听
 * @param callback 要移除的回调函数，不传则移除所有监听
 */
export function offDataUpdate(callback?: (data: any) => void) {
  uni.$off(EVENT_NAMES.DATA_UPDATED, callback);
}

// ===== 活动相关事件方法（已迁移到统一事件系统） =====
// 这些方法现在通过向后兼容包装器在文件末尾实现

// ===== 用户信息相关事件方法（已迁移到统一事件系统） =====
// 这些方法现在通过向后兼容包装器在文件末尾实现

// ===== 访客信息相关事件方法（已迁移到统一事件系统） =====
// 这些方法现在通过向后兼容包装器在文件末尾实现

// ===== 通用页面刷新事件 =====

/**
 * 发布页面刷新事件
 * @param pageName 页面名称
 * @param data 附加数据
 */
export function emitPageRefresh(pageName: string, data?: any) {
  uni.$emit(EVENT_NAMES.REFRESH_PAGE, { pageName, data });
}

/**
 * 监听页面刷新事件
 * @param callback 回调函数
 */
export function onPageRefresh(callback: (data: { pageName: string; data?: any }) => void) {
  uni.$on(EVENT_NAMES.REFRESH_PAGE, callback);
}

/**
 * 移除页面刷新监听
 */
export function offPageRefresh(callback?: (data: any) => void) {
  uni.$off(EVENT_NAMES.REFRESH_PAGE, callback);
}

// ===== 便捷方法 =====

/**
 * 清除所有事件监听（建议在应用退出时调用）
 */
export function clearAllListeners() {
  Object.values(EVENT_NAMES).forEach(eventName => {
    uni.$off(eventName);
  });
}

/**
 * 通用事件发布方法
 * @param eventName 事件名称
 * @param data 事件数据
 */
export function emit(eventName: string, data?: any) {
  uni.$emit(eventName, data);
}

/**
 * 通用事件监听方法
 * @param eventName 事件名称
 * @param callback 回调函数
 */
export function on(eventName: string, callback: (data?: any) => void) {
  uni.$on(eventName, callback);
}

/**
 * 通用事件移除方法
 * @param eventName 事件名称
 * @param callback 回调函数
 */
export function off(eventName: string, callback?: (data?: any) => void) {
  uni.$off(eventName, callback);
}

// ===== 向后兼容的包装器方法 =====
// 这些方法将现有的专用事件方法映射到新的统一事件系统

/**
 * 向后兼容：访客信息更新事件发送
 * @deprecated 建议使用 VisitorInfoEvents.emit 或 emitUnifiedEvent
 */
export function emitVisitorInfoUpdate(visitorId: string, action: 'add' | 'edit' | 'delete', visitorData?: any) {
  emitUnifiedEvent('visitor-info', action, {
    id: visitorId,
    data: visitorData
  });
}

/**
 * 向后兼容：访客信息更新事件监听
 * @deprecated 建议使用 VisitorInfoEvents.on 或 onUnifiedEvent
 */
export function onVisitorInfoUpdate(callback: (data: { visitorId: string; action: string; visitorData?: any }) => void) {
  return onUnifiedEvent<any>((eventData: IUnifiedEventData) => {
    // 转换为旧的数据格式
    callback({
      visitorId: String(eventData.id || ''),
      action: eventData.action,
      visitorData: eventData.data
    });
  }, {
    modules: ['visitor-info']
  });
}

/**
 * 向后兼容：移除访客信息更新监听
 * @deprecated 建议使用返回的取消函数或 offUnifiedEvent
 */
export function offVisitorInfoUpdate(callback?: (data: any) => void) {
  // 注意：由于新系统使用不同的事件名称，这里只能清除所有监听
  // 具体的callback移除需要使用新系统返回的取消函数
  if (!callback) {
    // 清除旧的专用事件监听
    uni.$off(EVENT_NAMES.VISITOR_INFO_UPDATED);
  } else {
    uni.$off(EVENT_NAMES.VISITOR_INFO_UPDATED, callback);
  }
}

/**
 * 向后兼容：活动更新事件发送
 * @deprecated 建议使用 ActivityEvents.emit 或 emitUnifiedEvent
 */
export function emitActivityUpdate(activityId: string, action: 'edit' | 'delete' | 'join' | 'create') {
  const unifiedAction = action === 'join' ? 'custom' : action === 'create' ? 'add' : action;
  emitUnifiedEvent('activity', unifiedAction, {
    id: activityId,
    customAction: action === 'join' ? 'join' : undefined
  });
}

/**
 * 向后兼容：活动更新事件监听
 * @deprecated 建议使用 ActivityEvents.on 或 onUnifiedEvent
 */
export function onActivityUpdate(callback: (data: { activityId: string; action: string }) => void) {
  return onUnifiedEvent<any>((eventData: IUnifiedEventData) => {
    // 转换为旧的数据格式
    const action = eventData.action === 'custom' ? eventData.customAction :
      eventData.action === 'add' ? 'create' : eventData.action;
    callback({
      activityId: String(eventData.id || ''),
      action: action || eventData.action
    });
  }, {
    modules: ['activity']
  });
}

/**
 * 向后兼容：移除活动更新监听
 * @deprecated 建议使用返回的取消函数或 offUnifiedEvent
 */
export function offActivityUpdate(callback?: (data: any) => void) {
  if (!callback) {
    uni.$off(EVENT_NAMES.ACTIVITY_UPDATED);
  } else {
    uni.$off(EVENT_NAMES.ACTIVITY_UPDATED, callback);
  }
}

/**
 * 向后兼容：用户信息更新事件发送
 * @deprecated 建议使用 UserInfoEvents.emit 或 emitUnifiedEvent
 */
export function emitUserInfoUpdate(userInfo: any, updateType: 'avatar' | 'name' | 'profile' | 'all' = 'all') {
  const action = updateType === 'avatar' ? 'custom' : 'edit';
  emitUnifiedEvent('user-info', action, {
    data: userInfo,
    customAction: updateType === 'avatar' ? 'avatar-update' : undefined,
    metadata: { updateType }
  });
}

/**
 * 向后兼容：用户信息更新事件监听
 * @deprecated 建议使用 UserInfoEvents.on 或 onUnifiedEvent
 */
export function onUserInfoUpdate(callback: (data: { userInfo: any; updateType: string }) => void) {
  return onUnifiedEvent<any>((eventData: IUnifiedEventData) => {
    // 转换为旧的数据格式
    const updateType = eventData.metadata?.updateType ||
      (eventData.customAction === 'avatar-update' ? 'avatar' : 'all');
    callback({
      userInfo: eventData.data,
      updateType
    });
  }, {
    modules: ['user-info']
  });
}

/**
 * 向后兼容：移除用户信息更新监听
 * @deprecated 建议使用返回的取消函数或 offUnifiedEvent
 */
export function offUserInfoUpdate(callback?: (data: any) => void) {
  if (!callback) {
    uni.$off(EVENT_NAMES.USER_INFO_UPDATED);
  } else {
    uni.$off(EVENT_NAMES.USER_INFO_UPDATED, callback);
  }
}

/**
 * 向后兼容：头像更新事件发送
 * @deprecated 建议使用 UserInfoEvents.emit 或 emitUnifiedEvent
 */
export function emitAvatarUpdate(photoId: string, userInfo?: any) {
  emitUnifiedEvent('user-info', 'custom', {
    data: userInfo,
    customAction: 'avatar-update',
    metadata: { photoId }
  });
}

/**
 * 向后兼容：头像更新事件监听
 * @deprecated 建议使用 UserInfoEvents.onAvatarUpdate 或 onUnifiedEvent
 */
export function onAvatarUpdate(callback: (data: { photoId: string; userInfo?: any }) => void) {
  return onUnifiedEvent<any>((eventData: IUnifiedEventData) => {
    // 只处理头像更新事件
    if (eventData.customAction === 'avatar-update') {
      callback({
        photoId: eventData.metadata?.photoId || '',
        userInfo: eventData.data
      });
    }
  }, {
    modules: ['user-info'],
    actions: ['custom']
  });
}

/**
 * 向后兼容：移除头像更新监听
 * @deprecated 建议使用返回的取消函数或 offUnifiedEvent
 */
export function offAvatarUpdate(callback?: (data: any) => void) {
  if (!callback) {
    uni.$off(EVENT_NAMES.USER_AVATAR_UPDATED);
  } else {
    uni.$off(EVENT_NAMES.USER_AVATAR_UPDATED, callback);
  }
}